package cn.bonoon.policy;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;

import cn.bonoon.kernel.menus.MenuableDefinition;
import cn.bonoon.kernel.menus.ModuleDefinition;
import cn.bonoon.kernel.menus.ModuleManager;
import cn.bonoon.kernel.menus.TabsDefinition;
import cn.bonoon.kernel.menus.privileges.PrivilegeInspector;
import cn.bonoon.kernel.security.LogonUserPrivilegeMapped;
import cn.bonoon.kernel.security.LogonUser;
import cn.bonoon.kernel.support.IOperator;
import cn.bonoon.kernel.support.services.PrivilegeSupport;
import cn.bonoon.kernel.util.MD5Util;

public class StandardPrivilegeStoragePolicy implements PrivilegeSupport, PrivilegePolicySourceable{
	
	private final static String LOGON_PRIVILEGE_CACHED_KEY = MD5Util.getMD5(StandardPrivilegeStoragePolicy.class.getName());

	@Autowired
	private ModuleManager moduleManager;
	
	private List<AccountPrivilegePolicy> policies;
	
	private PrivilegeSupport source;
	
	public void setPolicies(List<AccountPrivilegePolicy> policies) {
		this.policies = policies;
	}
	
	@Override
	public void set(PrivilegeSupport source) {
		this.source = source;
	}
	
	private boolean internalChecked(Object user, Object privilege){
		return null != policies && user instanceof LogonUser;
	}
	
	@Override
	public ModuleDefinition policy(Object user, Class<?> acceptClass, Object privilege) {
		
		if(internalChecked(user, privilege)){
			LogonUser luPrivilege = (LogonUser)user;
			
			for(AccountPrivilegePolicy policy : policies){
				if(policy.accept(acceptClass)){
					LogonUserPrivilegeMapped apMapped = new LogonUserPrivilegeMapped(moduleManager, privilege, policy);
					policy.doPolicy(luPrivilege, apMapped);
					luPrivilege.set(LOGON_PRIVILEGE_CACHED_KEY, apMapped);
					
					/*
					 * 登录用户权限的存储策略，只要有一个启作用就可以；
					 * 如果有多个启使用的，则只认第一个。
					 */
					return apMapped.getDefaultModule();
				}
			}
		}
		
		return null != source ? source.policy(user, acceptClass, privilege) : null;
	}
	
	private LogonUserPrivilegeMapped internalVisitor(IOperator user){
		LogonUserPrivilegeMapped apMapped = (LogonUserPrivilegeMapped)user.get(LOGON_PRIVILEGE_CACHED_KEY);
		//这里还要判断是否需要重新加载权限
		return apMapped.visit();
	}
	
	@Override
	public List<Long> getActions(MenuableDefinition item, IOperator user) {
		try{
			return internalVisitor(user).getActions(item);
		}catch (Exception e) {
			return null != source ? source.getActions(item, user) : null;
		}
	}

	@Override
	public PrivilegeInspector privilege(IOperator user, MenuableDefinition item) {
		try{
			return internalVisitor(user).privilege(item);
		}catch (Exception e) {
			return null != source ? source.privilege(user, item) : null;
		}
	}

	@Override
	public PrivilegeInspector privilege(IOperator user, ModuleDefinition module) {
		try{
			return internalVisitor(user).privilege(module);
		}catch (Exception e) {
			return null != source ? source.privilege(user, module) : null;
		}
	}

	@Override
	public PrivilegeInspector privilege(IOperator user, TabsDefinition tab) {
		try{
			return internalVisitor(user).privilege(tab);
		}catch (Exception e) {
			return null != source ? source.privilege(user, tab) : null;
		}
	}

	@Override
	public PrivilegeInspector privilege(IOperator user, String mid, String cid) {
		try{
			return internalVisitor(user).privilege(mid, cid);
		}catch (Exception e) {
			return null != source ? source.privilege(user, mid, cid) : null;
		}
	}

}
